﻿// TestCaseModel
// (c)2007 Mark Bulmahn. mBulmahn@web.de
// License: GPL 2.0
// Project: TestCaseGenerator. http://www.codeplex.com/TestCaseGenerator

using System;
using System.Collections.Generic;
using System.Text;
using PICTWrapper;

namespace TestCaseModel
{
    /// <summary>
    /// This test case generator is just a frontend for handling
    /// the communication with the "Pairwise Independent Combinatorial Testing"
    /// tool by Jacek Czerwonka of Microsoft Corp. In fact it again uses the
    /// class PictWrapper which handles the PICT.EXE. Look there for more information.
    /// The algorithm which is used by this tool can reduce test cases significantly
    /// by using a pairwise algorithm. More on the theory behind this: 
    /// http://www.pairwise.org.
    /// </summary>
    class PictGenerator : ITcGenerator
    {
        int orderOfCombination = 0;
        public int OrderOfCombination
        {
            get { return orderOfCombination; }
            set { orderOfCombination = value; }
        }

        string[,] parameterCombinations;
        public string[,] ParameterCombinations
        {
            get { return parameterCombinations; }
            set { parameterCombinations = value; }
        }

        Parameters modelParameters = null;
        public Parameters ModelParameters
        {
            get { return modelParameters; }
            set { modelParameters = value; }
        }


        public void Calculate()
        {
            // build an input file for pict and execute it
            List<string> pictInput = BuildPictModelFile();
            // pictInput.Add("if [Anz. Anmeldung] <> 2 THEN [eingang Datum der beiden Anmeldungen gleich]=\"nein\";");
            string[] pictOutput = PictWrapper.DoPict(pictInput, orderOfCombination);

            // now fill the parameter combinations from the raw output
            
            parameterCombinations = new string[pictOutput.Length - 1, modelParameters.Values.Count];
            int i = 0;
            foreach (string s in pictOutput)
            {
                if (s.Trim() != "")
                {
                    int e = 0;
                    string[] line = s.Split('\t');
                    foreach (string element in line)
                    {
                        parameterCombinations[i, e] = this.Decode(element);
                        e++;
                    }
                    i++;
                }
            }
        }


        private List<string> BuildPictModelFile()
        {
            List<string> result = new List<string>();
            foreach (Parameter p in modelParameters.Values)
            {
                string line = this.Encode(p.Name) + ":";
                foreach (EquivClass val in p.Classes)
                {
                    line += this.Encode(val.Id) + ",";
                }
                line = line.Substring(0, line.Length - 1);
                result.Add(line);
            }
            return result;
        }

        /// <summary>
        /// Encode a string for use in PICT because commas are treated
        /// as separators by PICT even if they are enclosed by ""
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        private string Encode(string p)
        {
            byte[] buf = Encoding.Unicode.GetBytes(p);
            return Convert.ToBase64String(buf);
        }

        private string Decode(string p)
        {
            byte[] buf = Convert.FromBase64String(p);
            return Encoding.Unicode.GetString(buf);
        }
    }
}
